package avicit.bdp.dcs.semistructure.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.EntityUtils;
import avicit.bdp.common.utils.database.ColumnInfo;
import avicit.bdp.dcs.semistructure.dao.TemplateFieldDao;
import avicit.bdp.dcs.semistructure.dto.TemplateFieldDTO;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @金航数码科技有限责任公司 @作者：liyb @邮箱：liyb@avic-digital.com @创建时间：2023-04-03 14:09 @类说明：文件模板字段 @修改记录：
 */
@Service
@Transactional
public class TemplateFieldService extends BaseService<TemplateFieldDao, TemplateFieldDTO> {

  private static final Logger logger = LoggerFactory.getLogger(TemplateFieldService.class);

  private static String TEMPLATE_FILE_PATH = "template.xlsx";

  @Value("${file.templateColumnRule}")
  private String templateColumnRule;

  @Autowired private TemplateFieldDao templateFieldDao;

  /**
   * 分页查询模板字段
   *
   * @param name
   * @param pageNo
   * @param pageSize
   * @return
   */
  public QueryRespBean<TemplateFieldDTO> getTemplateFieldList(
      String templateId, String name, Integer pageNo, Integer pageSize) {
    QueryRespBean<TemplateFieldDTO> queryRespBean = new QueryRespBean<>();
    com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);

    Page<TemplateFieldDTO> fieldList = templateFieldDao.getTemplateFieldList(templateId, name);
    queryRespBean.setResult(fieldList);
    BdpLogUtil.log4Query(queryRespBean);
    return queryRespBean;
  }

  /**
   * 批量插入
   *
   * @param fieldList
   * @return
   */
  public int batchInsertTemplateField(List<TemplateFieldDTO> fieldList, String templateId) {
    checkField(fieldList);

    if (CollectionUtils.isNotEmpty(fieldList)) {
      for (TemplateFieldDTO field : fieldList) {
        field.setId(ComUtil.getId());
        field.setTemplateId(templateId);

        EntityUtils.setCreateAndUpdateInfo(field);
      }

      return templateFieldDao.batchInsertTemplateField(fieldList);
    }
    return 0;
  }

  /**
   * 批量修改
   *
   * @param fieldList
   * @return
   */
  public int batchUpdateTemplateField(List<TemplateFieldDTO> fieldList, String templateId) {
    checkField(fieldList);

    // 先删除再新增
    templateFieldDao.deleteByTemplateId(templateId);

    if (CollectionUtils.isNotEmpty(fieldList)) {
      for (TemplateFieldDTO field : fieldList) {
        field.setId(ComUtil.getId());
        field.setTemplateId(templateId);

        EntityUtils.setCreateAndUpdateInfo(field);
      }

      return templateFieldDao.batchInsertTemplateField(fieldList);
    }
    return 0;
  }

  private void checkField(List<TemplateFieldDTO> fieldList) {
    if (CollectionUtils.isNotEmpty(fieldList)) {
      for (TemplateFieldDTO templateField : fieldList) {
        // 对模板列字段进行校验
        if (!isValid(templateColumnRule, templateField.getName())) {
          throw new BusinessException(
              String.format("模板字段只允许数字，字母大小写，下划线，横杠，并且长度限制100，字段:%s不合法", templateField.getName()));
        }
      }
    }
  }

  private boolean isValid(String regex, String name) {
    boolean flag = true;
    if (name.equals("\\t")) {
      name = name.replace("\\t", "t");
    }

    if (name.contains("\"")) {
      name = name.replace("\"", "");
    }

    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(name);
    if (!matcher.matches()) {
      flag = false;
    }
    return flag;
  }

  /**
   * 根据templateId删除
   *
   * @param templateId
   * @return
   */
  public void deleteByTemplateId(String templateId) {
    templateFieldDao.deleteByTemplateId(templateId);
  }

  /**
   * 下载标准模板
   *
   * @param response
   */
  public void downloadTemplate(HttpServletResponse response) {
    InputStream inputStream = null;
    OutputStream outputStream = null;

    try {
      // step1:设置消息头
      response.setContentType("application/octet-stream");
      String downloadFileName = "template.xlsx";

      // 解决URLEncoder.encode空格变+号问题
      downloadFileName = downloadFileName.replace("+", "%20");
      response.setHeader(
          HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + downloadFileName);

      // step2：返回数据流
      inputStream = this.getClass().getClassLoader().getResourceAsStream(TEMPLATE_FILE_PATH);
      outputStream = response.getOutputStream();
      byte[] b = new byte[1024];
      int len;
      while ((len = inputStream.read(b)) > 0) {
        outputStream.write(b, 0, len);
      }

      outputStream.flush();
    } catch (Exception e) {
      logger.error("下载模板示例文件失败,errMsg={}", e);
      throw new BusinessException(String.format("下载模板示例文件%s失败", TEMPLATE_FILE_PATH));
    } finally {
      try {
        if (inputStream != null) {
          inputStream.close();
        }
        if (outputStream != null) {
          outputStream.close();
        }
      } catch (Exception e) {
        logger.error("下载模板示例文件失败，errMsg", e);
      }
    }
  }

  /**
   * 根据模板ID查询模板字段
   *
   * @param templateId
   * @return
   * @throws Exception
   */
  public List<ColumnInfo> getTemplateColumnListById(String templateId) throws Exception {
    List<ColumnInfo> columnInfoList = new ArrayList<>();

    TemplateFieldDTO templateField = new TemplateFieldDTO();
    templateField.setTemplateId(templateId);
    List<TemplateFieldDTO> templateFieldList = templateFieldDao.select(templateField);
    if (CollectionUtils.isNotEmpty(templateFieldList)) {
      for (TemplateFieldDTO templateFieldDTO : templateFieldList) {
        ColumnInfo columnInfo = new ColumnInfo();
        columnInfo.setName(templateFieldDTO.getName());
        columnInfo.setType(templateFieldDTO.getType());
        // 存储字段顺序
        columnInfo.setPrecision(templateFieldDTO.getOrderBy());
        columnInfoList.add(columnInfo);
      }
    }
    return columnInfoList;
  }

  public List<TemplateFieldDTO> getTemplateFieldListById(String templateId) {
    TemplateFieldDTO templateField = new TemplateFieldDTO();
    templateField.setTemplateId(templateId);
    return templateFieldDao.select(templateField);
  }
}
